/**
 * @file common.c
 * @author fishmwei <fishmwei@qq.com>
 * @brief print message to buffers
 *
 * @copyright
 * Copyright All Reserved
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#define _GNU_SOURCE
#include <sys/cdefs.h>

#include "common.h"

#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <inttypes.h>
#include <pthread.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include "log.h"

/**
*@ Description: 
*@ options: [in, out] 选项解析结果
*@ return void
*/
void *clog_realloc(void *ptr, size_t size)
{
    void *new_mem;

    new_mem = realloc(ptr, size);
    if (!new_mem)
    {
        free(ptr);
    }

    return new_mem;
}

int clog_vsprintf(char **str, int *str_len, int offset, const char *format, va_list ap)
{
    va_list ap2;
    int req_len;

    if (!*str_len) 
    {
        *str_len = CLOG_MSG_LEN_START;
        *str = malloc(*str_len);
        if (!*str) 
        {
            req_len = -1;
            goto cleanup;
        }
    }

    va_copy(ap2, ap);

    /* learn how much bytes are needed */
    req_len = vsnprintf(*str + offset, *str_len - offset, format, ap);
    if (req_len == -1) 
    {
        goto cleanup;
    }
    else if (req_len >= *str_len - offset) 
    {
        /* the length is not enough */
        *str_len = req_len + offset + 1;
        *str = clog_realloc(*str, *str_len);
        if (!*str) 
        {
            req_len = -1;
            goto cleanup;
        }

        /* now print the full message */
        req_len = vsnprintf(*str + offset, *str_len - offset, format, ap2);
        if (req_len == -1) 
        {
            goto cleanup;
        }
    }

cleanup:
    if (req_len == -1) 
    {
        free(*str);
        *str = NULL;
    }
    va_end(ap2);
    return req_len;
}

int clog_sprintf(char **str, int *str_len, int offset, const char *format, ...)
{
    va_list ap;
    int ret;

    va_start(ap, format);
    ret = clog_vsprintf(str, str_len, offset, format, ap);
    va_end(ap);

    return ret;
}
  
 